#ifndef NUMBERTOOLS_H
#define NUMBERTOOLS_H

#include "warlocklib_global.h"

#include <functional>
#include <limits>

WARLOCK_NS_BEGIN

template <typename N>
bool WARLOCKLIBSHARED_EXPORT isNumberEquals(N a, N b) {
  if (std::numeric_limits<N>::is_integer)
    return a - b == 0;
  auto x = a - b;
  return x <= std::numeric_limits<double>::epsilon();
}

template <typename N>
N positiveGate(N x) {
  return x < 0 ? 0 : x;
}

template <typename N>
N smaller(N a, N b) {
  return a < b ? a : b;
}

template <typename M>
M larger(M a, M b) {
  return a > b ? a : b;
}

template <typename N>
std::function<N(N)> buildRangeGate(N min, N max) {
  auto f = [=](N n) {
    if (n > max)
      return max;
    if (n < min)
      return min;
    return n;
  };
  return f;
}

template <typename N>
std::function<bool(N)> buildRangeChecker(
  N min, N max, bool contains_min = true, bool contains_max = true) {
  auto f = [=](N n) {
    bool v1 = min < n && n < max;
    bool v2 = contains_min && n == min;
    bool v3 = contains_max && n == max;
    return v1 || v2 || v3;
  };
  return f;
}

WARLOCK_NS_END
#endif // NUMBERTOOLS_H
